﻿const GomokuProtocol = require("../GomokuCommon/Protocol")

/**
 * 服务器类的构造方法。
 */
function Server() {
    const mOnlineUsers = new Map()  // 在线用户列表

    // 创建服务
    const server = require("nodejs-websocket").createServer(onAccept)

    // 监听
    server.listen(GomokuProtocol.SERVER_PORT, GomokuProtocol.SERVER_IP, function() {
        // 显示 IP 地址和端口号
        var address = server.socket._connectionKey.split(":")
        const ip = address[1]
        const port = address[2]
        console.log("IP: " + ip)
        console.log("Port: " + port)
    }) 

    /**
     * 处理寻找其它用户请求。
     * @param request   寻找其它用户请求
     * @param client    客户端
     */
    function handleFindUsers(request, client) {
        // 创建结果
        const usernameList = new Array()
        mOnlineUsers.forEach(function(value, key) {
            // 跳过自己的名字
            if (request.mUsername != key) {
                usernameList.push(key)
            }
        }) 
        const result = new GomokuProtocol.FindUsersResult(usernameList)

        // 发送结果
        sendData(client, result)
    }

    /**
     * 处理登录请求。
     * @param request   请求
     * @param client    客户端
     */
    function handleLogon(request, client) {
        var result

        // 如果已登录，则直接返回
        const user = mOnlineUsers.get(request.mUsername)
        if (user != null) {
            result = new GomokuProtocol.LogonResult()
            sendData(client, result)
            return
        }
        
        // 保存用户
        mOnlineUsers.set(request.mUsername, client)

        // 创建结果
        result = new GomokuProtocol.LogonResult(request.mUsername)

        // 发送结果
        sendData(client, result)
    }

    /**
     * 处理协议。
     * @param pro   协议
     */
    function handleProtocol(pro) {
        // 如果目标用户不在线则返回
        const rivalUser = mOnlineUsers.get(pro.mUsername)
        if (rivalUser == null) {
            return
        }

        // 发送给目标用户
        sendData(rivalUser, pro)
    }

    /**
     * 处理退出游戏请求。
     * @param quitGame  请求
     * @param client    客户端
     */
    function handleQuitGame(quitGame, client) {
        // 广播该用户的请求
        mOnlineUsers.forEach(function(value, key) {
            sendData(value, quitGame)
        }) 

        // 将该用户从在线列表移除
        mOnlineUsers.delete(quitGame.mUsername)

        // 关闭客户端
        client.close()
    }

    /**
     * 客户端连接服务器事件的响应方法。
     * @param client    客户端
     */
    function onAccept(client) {
        /**
         * 关闭事件的响应方法。
         */
        function onClose() {
            mOnlineUsers.forEach(function(value, key) {
                if (client == value) {
                    const quitGame = new GomokuProtocol.QuitGame(key)
                    handleQuitGame(quitGame, client)
                }
            }) 
        }

        /**
         * 接收到数据的响应方法。
         * @param data  数据
         */
        function onReceive(data) {
            // 将数据转换成协议
            var pro = JSON.parse(data)

            // 处理协议
            switch (pro.mType) {
                case GomokuProtocol.ProtocolType.FIND_USERS:
                    handleFindUsers(pro, client)
                    break 
                case GomokuProtocol.ProtocolType.LOGON:
                    handleLogon(pro, client)
                    break 
                case GomokuProtocol.ProtocolType.QUIT_GAME:
                    handleQuitGame(pro, client)
                    break 
                default:
                    handleProtocol(pro)
                    break 
            }
        }

        client.on("text", onReceive)
        client.on("close", onClose)
        client.on("error", function(code){})
    }

    /**
     * 发送数据。
     * @param client    客户端
     * @param pro       协议
     */
    function sendData(client, pro) {
        var text = JSON.stringify(pro)
        client.sendText(text)
    }
}

new Server()
